home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 June: Reference Library / Dev.CD Jun 99 RL Disk 1.toast / Technical Documentation / Develop / Additional Articles / Developing Symbiotic Apps / Symbiotic Samples / Symbiotic server source / flexibled & simpled / handlers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-03  |  10.1 KB  |  331 lines  |  [TEXT/CWIE]

  1. /* handlers.c -- Apple Event Handlers for Trident UNIX daemon.
  2.  * %F%  %I%
  3.  *
  4.  * Original Author: Chris Jalbert
  5.  * Copyright 1993-1996 Apple Computer, Inc.
  6.  * All Rights Reserved.
  7.  *
  8.  * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
  9.  * The copyright notice above does not evidence any actual or
  10.  * intended publication of such source code.
  11.  *
  12.  * History:
  13.  * 8/19/96    Chris Jalbert
  14.  *    Initial check in of new sample.
  15.  *    Note the similarities between this and the Javelin daemon stuff.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <time.h>
  21. #include <string.h>
  22.  
  23. /* MacOS Universal headers for compatability. */
  24. #include <Types.h>
  25. #include <AppleEvents.h>
  26. #include <AERegistry.h>
  27.  
  28. #include "tridentd.h"
  29. #include "AIXAESuite.h" 
  30. #include "debug.h"
  31.  
  32.  
  33. extern OSErr AEInit (void) ;
  34. extern Boolean TimeToQuit ;
  35.  
  36.  
  37. /******************************************************************************
  38.     ==>  Private Globals  <==
  39. ******************************************************************************/
  40. static char    *_ServerVersion = "1.01" ;
  41. static char *_UnknownClient = "Client shouldn't be connected to this service!?!" ;
  42.  
  43.  
  44. /******************************************************************************
  45.     ==>  Static Functions  <==
  46. ******************************************************************************/
  47. static OSErr _StuffResultInReply (
  48.     AppleEvent    *reply,
  49.     char        cNumber,
  50.     const char    *szpErr)
  51.     {
  52.     OSErr                result ;
  53.  
  54.     if (cNumber != 'S')
  55.         DBGM (tprintf ("status code = '%c', string = %s",
  56.                     cNumber, (szpErr ? szpErr : "Success\n"))) ;
  57.  
  58.     result = AEPutParamPtr (reply, keyErrorNumber, typeChar,
  59.                             &cNumber, sizeof (char)) ;
  60.     if (szpErr != NULL)
  61.         result = AEPutParamPtr (reply, keyErrorString, typeChar,
  62.                                 szpErr, strlen (szpErr)) ;
  63.     return result ;
  64.     }
  65.  
  66.  
  67. /*-----------------------------------------------------------------------------
  68.     _HandleNullEvent() handles the first event from the client, which
  69.     should only be sent once. It define's the client's ID number for
  70.     this connection.
  71. -----------------------------------------------------------------------------*/
  72. static pascal OSErr _HandleNullEvent (
  73.     const AppleEvent    *msg,
  74.     AppleEvent            *reply,
  75.     long                refcon)
  76.     {
  77. //    ClientPtr            conn ;
  78.  
  79.     DBGM ("\n<<< HandleNullEvent()\n") ;
  80.  
  81.     /* Find the client this request belongs to. */
  82. //    if (NULL == (conn = FindClient (Clients, msg)))
  83. //        return _StuffResultInReply (reply, 'F', _UnknownClient) ;
  84.     return _StuffResultInReply (reply, 'S', NULL) ;
  85.     }
  86.  
  87. /*-----------------------------------------------------------------------------
  88.     _HandleVersionEvent() handles the version event from the client, which
  89.     should only be sent once. If the major numbers don't match (and hence
  90.     the messaging protocol doesn't either), failure will be returned and
  91.     the connection dropped.
  92.     The client record should be freed (or marked to be freed).
  93. -----------------------------------------------------------------------------*/
  94. static pascal OSErr _HandleVersionEvent (
  95.     const AppleEvent    *msg,
  96.     AppleEvent            *reply,
  97.     long                refcon)
  98.     {
  99.     OSErr                result ;
  100.     ClientPtr            conn ;
  101.     DescType            returnedType ;
  102.     Size                returnedSize ;
  103.     char                szClientVer [BUFSIZ], szServerVer [16] ;
  104.  
  105.     DBGM ("\n<<< HandleVersionEvent()\n") ;
  106.  
  107.     /* Pull out the version parameter. */
  108.     if (result = AEGetParamPtr (msg, keyAEMyVersion, typeChar, &returnedType,
  109.                                 szClientVer,
  110.                                 (sizeof (szClientVer) - 1), &returnedSize))
  111.         {
  112.         _StuffResultInReply (reply, 'F',
  113.                             "Required parameter (keyAEMyVersion) not found!\n") ;
  114.         return result ;
  115.         }
  116.     szClientVer[returnedSize] = '\0' ;
  117.     DBGM (tprintf ("Server v%s, client v%s\n", _ServerVersion, szClientVer)) ;
  118.  
  119.     /* Find the client this request belongs to. */
  120.     if (NULL == (conn = FindClient (msg)))
  121.         return _StuffResultInReply (reply, 'F', _UnknownClient) ;
  122.  
  123.     /* The major version number defines the protocol. */
  124.     strcpy (szServerVer, _ServerVersion) ;
  125.     strtok (szServerVer, ".") ;
  126.     strtok (szClientVer, ".") ;
  127.  
  128.     /* If the major versions don't match, puke and close the client. */
  129.     if (strcmp (szServerVer, szClientVer))
  130.         {
  131.         DBGM ("Protocol versions don't match!\n") ;
  132.         _StuffResultInReply (reply, 'F', _ServerVersion) ;
  133.         CloseClient (conn) ;
  134.         return noErr ;
  135.         }
  136.  
  137.     /* There might be a reason to send the OS version, but I can't figure why. */
  138.     result = AEPutParamPtr (reply, keyAEMyVersion, typeChar,
  139.                             _ServerVersion, strlen (_ServerVersion)) ;
  140.     return _StuffResultInReply (reply, 'S', NULL) ;
  141.     }
  142.  
  143. /*-----------------------------------------------------------------------------
  144.     _HandleIntervalEvent() handles the interval event from the client, which
  145.     will be sent immediately following the version event to signal that the
  146.     client is ready to accept messages.
  147.     Multiple interval events are allowed to modify the update frequency.
  148. -----------------------------------------------------------------------------*/
  149. static pascal OSErr _HandleIntervalEvent (
  150.     const AppleEvent    *msg,
  151.     AppleEvent            *reply,
  152.     long                refcon)
  153.     {
  154.     OSErr                result ;
  155.     ClientPtr            conn ;
  156.     DescType            returnedType ;
  157.     Size                returnedSize ;
  158.     int                    nInterval ;
  159.  
  160.     DBGM ("\n<<< HandleInterval()\n") ;
  161.  
  162.     /* Pull out the interval parameter. */
  163.     if (result = AEGetParamPtr (msg, keyInterval, typeInteger, &returnedType,
  164.                                 &nInterval, sizeof (nInterval), &returnedSize))
  165.         {
  166.         _StuffResultInReply (reply, 'F',
  167.                             "Required parameter (keyAEInteger) not found!\n") ;
  168.         return result ;
  169.         }
  170.  
  171.     /* Find the client this request belongs to. */
  172.     if (NULL == (conn = FindClient (msg)))
  173.         return _StuffResultInReply (reply, 'F', _UnknownClient) ;
  174.  
  175.     /* Set the stuff. */
  176.     DBGM (tprintf ("New interval for client %ld is %d seconds.\n",
  177.                     conn->session, nInterval)) ;
  178.     ClientSetInterval (conn, nInterval) ;
  179.  
  180.     return _StuffResultInReply (reply, 'S', NULL) ;
  181.     }
  182.  
  183. /*-----------------------------------------------------------------------------
  184.     _HandleHeartbeatEvent() handles heartbeat events from the client,
  185.     which can be sent multiple times at random intervals. Currently, the
  186.     client only sends heartbeat events after receiving them from the
  187.     daemon.
  188. -----------------------------------------------------------------------------*/
  189. static pascal OSErr _HandleHeartbeatEvent (
  190.     const AppleEvent    *msg,
  191.     AppleEvent            *reply,
  192.     long                refcon)
  193.     {
  194.     ClientPtr            conn ;
  195.  
  196.     DBGM ("\n<<< HandleHeartBeat ") ;
  197.  
  198.     if (NULL == (conn = FindClient (msg)))
  199.         return _StuffResultInReply (reply, 'F', _UnknownClient) ;
  200.  
  201.     time (&conn->lastExchange) ;
  202.     conn->missedHeartbeats = 0 ;
  203.     DBG ("(conn #%ld)\n", conn->session) ;
  204.     return _StuffResultInReply (reply, 'S', NULL) ;
  205.     }
  206.  
  207. /*-----------------------------------------------------------------------------
  208.     _HandleQuit() handles the quit event from the client, which will be
  209.     sent once as the connection is closed. The client connection is invalid
  210.     after receiving this event.
  211.     Currently, any quit events not issued by a client are considered from
  212.     the system, forcing a shutdown of the service daemon.
  213. -----------------------------------------------------------------------------*/
  214. static pascal OSErr _HandleQuit (
  215.     const AppleEvent    *msg,
  216.     AppleEvent            *reply,
  217.     long                refcon)
  218.     {
  219.     ClientPtr            conn ;
  220.  
  221.     DBGM ("\n<<< HandleQuit()\n") ;
  222.  
  223.     /* If the quit message doesn't come from a client, assume it is from
  224.      * the system notifying us of pending death.
  225.      */
  226.     if (NULL != (conn = FindClient (msg)))
  227.         CloseClient (conn) ;
  228.  
  229.     return noErr ;
  230.     }
  231.  
  232. /*-----------------------------------------------------------------------------
  233.     The following four functions handle the four required Apple Events.
  234.     They are mostly useless for a background app like this one.
  235. -----------------------------------------------------------------------------*/
  236. static pascal OSErr _HandleOpenApp (
  237.     const AppleEvent    *msg,
  238.     AppleEvent            *reply,
  239.     long                refcon)
  240.     {
  241.     DBGM ("\n<<< HandleOpenApp()\n") ;
  242.     return noErr ;
  243.     }
  244.  
  245. static pascal OSErr _HandleOpenDocs (
  246.     const AppleEvent    *msg,
  247.     AppleEvent            *reply,
  248.     long                refcon)
  249.     {
  250.     DBGM ("\n<<< HandleOpenDocs()\n") ;
  251.     return errAEEventNotHandled ;
  252.     }
  253.  
  254. static pascal OSErr _HandlePrintDocs (
  255.     const AppleEvent    *msg,
  256.     AppleEvent            *reply,
  257.     long                refcon)
  258.     {
  259.     DBGM ("\n<<< HandlePrintDocs()\n") ;
  260.     return errAEEventNotHandled ;
  261.     }
  262.  
  263. static pascal OSErr _HandleQuitApp (
  264.     const AppleEvent    *msg,
  265.     AppleEvent            *reply,
  266.     long                refcon)
  267.     {
  268.     DBGM ("\n<<< HandleQuitApp()\n") ;
  269.     TimeToQuit = true ;
  270.     return noErr ;
  271.     }
  272.  
  273.  
  274. /******************************************************************************
  275.     ==>  More Private Globals  <==
  276. ******************************************************************************/
  277. typedef struct _tagAEHandler
  278.     {
  279.     AEEventID                eventID ;
  280.     AEEventHandlerProcPtr    handler ;
  281.     } _AEHandler ;
  282.  
  283. static _AEHandler _AIXHandlerTable [] = {
  284.     { kAENull,                _HandleNullEvent },
  285.     { kAEMyVersion,            _HandleVersionEvent },
  286.     { kAEInterval,            _HandleIntervalEvent },
  287.     { kAEHeartBeat,            _HandleHeartbeatEvent },
  288.     { kAEQuitApplication,    _HandleQuit }
  289. } ;
  290. static _AEHandler _RequiredHandlerTable [] = {
  291.     { kAEOpenApplication,    _HandleOpenApp },
  292.     { kAEOpenDocuments,        _HandleOpenDocs },
  293.     { kAEPrintDocuments,    _HandlePrintDocs },
  294.     { kAEQuitApplication,    _HandleQuitApp }
  295. } ;
  296.  
  297.  
  298. /******************************************************************************
  299.     ==>  Global (Exported) Functions  <==
  300. ******************************************************************************/
  301. /*-----------------------------------------------------------------------------
  302.     InitAEStuff() installs all the handlers defined in the handler tables.
  303. -----------------------------------------------------------------------------*/
  304. OSErr InitAEStuff (
  305.     long            refcon)
  306.     {
  307.     register OSErr    result = noErr;
  308.     register int    i ;
  309.  
  310. #ifdef _AIX
  311.     AEInit () ;
  312. #endif
  313.  
  314.     /* Install required event handlers. */
  315.     i = sizeof (_RequiredHandlerTable) / sizeof (_AEHandler) ;
  316.     while (!result && i--)
  317.         result = AEInstallEventHandler (kCoreEventClass, 
  318.                         _RequiredHandlerTable[i].eventID,
  319.                         NewAEEventHandlerProc (_RequiredHandlerTable[i].handler),
  320.                         refcon, false) ;
  321.  
  322.     /* Install AIX (OK, A/UX), app-specific event handlers. */
  323.     i = sizeof (_AIXHandlerTable) / sizeof (_AEHandler) ;
  324.     while (!result && i--)
  325.         result = AEInstallEventHandler (kAEAUXSuite, 
  326.                         _AIXHandlerTable[i].eventID,
  327.                         NewAEEventHandlerProc (_AIXHandlerTable[i].handler),
  328.                         refcon, false) ;
  329.     return result ;
  330.     }
  331.